package com.xiaohe66.web.domain.sys.sec.entity;

import com.xiaohe66.common.util.Assert;
import com.xiaohe66.common.web.sec.ICurrentAccount;
import com.xiaohe66.web.domain.account.value.AccountId;
import com.xiaohe66.web.domain.account.value.AccountName;
import com.xiaohe66.web.domain.sys.sec.value.PermissionName;
import com.xiaohe66.web.domain.sys.sec.value.RoleName;
import com.xiaohe66.web.integration.domain.Entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NonNull;
import lombok.ToString;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * @author xiaohe
 * @since 2021.10.28 16:11
 */
@ToString
@Getter
@Builder
@AllArgsConstructor
public class CurrentAccount implements Entity<AccountId>, ICurrentAccount {

    @NonNull
    private final AccountId id;

    @NonNull
    private final AccountName name;

    @Builder.Default
    private Set<RoleName> roleNames = new HashSet<>();

    @Builder.Default
    private Set<PermissionName> permissionNames = new HashSet<>();

    @Override
    public AccountId getId() {
        return id;
    }

    @Override
    public Collection<RoleName> getRoleNames() {
        return roleNames;
    }

    @Override
    public Collection<PermissionName> getPermissionNames() {
        return permissionNames;
    }

    @Override
    public void addRole(String role) {
        Assert.requireNotEmpty(role);
        roleNames.add(new RoleName(role));
    }

    @Override
    public void addRole(@NonNull Collection<String> roles) {
        for (String role : roles) {
            addRole(role);
        }
    }

    @Override
    public void addRole(@NonNull String... roles) {
        for (String role : roles) {
            addRole(role);
        }
    }

    @Override
    public void removeRole(@NonNull String role) {
        roleNames.remove(new RoleName(role));
    }

    @Override
    public void addPermission(String permission) {
        Assert.requireNotEmpty(permission);
        permissionNames.add(new PermissionName(permission));
    }

    @Override
    public void addPermission(@NonNull Collection<String> permissions) {
        for (String permission : permissions) {
            addRole(permission);
        }
    }

    @Override
    public void addPermission(@NonNull String... permissions) {
        for (String permission : permissions) {
            addRole(permission);
        }
    }

    @Override
    public void removePermission(@NonNull String permission) {
        permissionNames.remove(new PermissionName(permission));
    }

    @Override
    public boolean hasRole(@NonNull String roleName) {
        return roleNames.contains(new RoleName(roleName));
    }

    @Override
    public boolean hasRoleAll(@NonNull String... roleNames) {
        for (String roleName : roleNames) {
            if (!this.roleNames.contains(new RoleName(roleName))) {
                return false;
            }
        }
        return true;
    }

    @Override
    public boolean hasRoleAll(@NonNull Collection<String> roleNames) {
        for (String roleName : roleNames) {
            if (!this.roleNames.contains(new RoleName(roleName))) {
                return false;
            }
        }
        return true;
    }

    @Override
    public boolean hasRoleAny(@NonNull String... roleNames) {
        for (String roleName : roleNames) {
            if (this.roleNames.contains(new RoleName(roleName))) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean hasRoleAny(@NonNull Collection<String> roleNames) {
        for (String roleName : roleNames) {
            if (this.roleNames.contains(new RoleName(roleName))) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean hasPermission(@NonNull String permissionName) {
        return permissionNames.contains(new PermissionName(permissionName));
    }

    @Override
    public boolean hasPermissionAll(@NonNull String... permissionNames) {
        for (String permissionName : permissionNames) {
            if (!this.permissionNames.contains(new PermissionName(permissionName))) {
                return false;
            }
        }
        return true;
    }

    @Override
    public boolean hasPermissionAll(@NonNull Collection<String> permissionNames) {
        for (String permissionName : permissionNames) {
            if (!this.permissionNames.contains(new PermissionName(permissionName))) {
                return false;
            }
        }
        return true;
    }

    @Override
    public boolean hasPermissionAny(@NonNull String... permissionNames) {
        for (String permissionName : permissionNames) {
            if (this.permissionNames.contains(new PermissionName(permissionName))) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean hasPermissionAny(@NonNull Collection<String> permissionNames) {
        for (String permissionName : permissionNames) {
            if (this.permissionNames.contains(new PermissionName(permissionName))) {
                return true;
            }
        }
        return false;
    }

}
